#ifndef __CLX_FORMAT_HPP__
#define __CLX_FORMAT_HPP__ 

#include "util.hpp"
#include "level.hpp"
#include "message.hpp"

#include <vector>
#include <assert.h>
#include <sstream>


namespace clxlog {
  class FormatItem {
    public:
      using ptr = std::shared_ptr<FormatItem>;
      virtual void format(std::ostream& out, const clxlog::LogMsg msg) = 0;
  };

  class TimeFormatItem final : public FormatItem {
    public:
      TimeFormatItem(std::string time_format = "%H:%M:%S") :_time_format(time_format){}
      virtual void format(std::ostream& out, const clxlog::LogMsg msg) override {
        struct tm time;
        localtime_r(&msg._ctime, &time);
        char str_time[128]  = {0};
        strftime(str_time, 128, _time_format.c_str(), &time);
        out << str_time;
      }
    private:
      std::string _time_format;
  };

  class Formatter {
    public:
      using ptr = std::shared_ptr<Formatter>;
      Formatter(const std::string format_str) 
        : _format_str(format_str)
      { assert(prase_format_str()); }

      bool prase_format_str();

      void format(std::ostream& out, LogMsg& msg) {
        for (auto& item : _items) {
          item->format(out, msg);
        }
      }

      std::string format(LogMsg& msg) {
        std::stringstream ss;
        format(ss, msg);
        return ss.str();
      }
    private:
      std::string _format_str;
      std::vector<FormatItem::ptr> _items;
  };
}



#endif
